import utils from "./utils";

export default {
    name: 'render',
    props: {
        tree: { type: Array },
        effect: { type: String, default: "" },
        readonly: { type: Boolean, default: false }
    },
    created() {
        this.inc = 1;
    },
    data() {
        return {
            select: null,
        };
    },
    render(h) {
        var vue = this;
        var store = utils.store;

        function dfs(data, sigle) {
            let { node, parent, path, i } = data;
            path = path || '/';
            if (!node) return node;
            if (node instanceof Array) {
                return node.map((item, j) => dfs({ node: item, parent, path: path + j + '/', i: j }, true));
            }
            if (typeof node === 'string') return node;
            if (!node.key) Object.defineProperty(node, 'key', { configurable: false, value: vue.inc++, enumerable: false });
            let edr_abs = node.class && node.class.edr_abs;
            let item = {
                attrs: { dragable: (vue.effect && !edr_abs) },
                class: {}
            };
            let on = {};
            if (vue.effect) {
                if (!edr_abs) { // 拖拽
                    on.dragstart = function(e) {
                        if (e.target !== e.currentTarget) return;
                        if (vue.effect == "move") { // 拖动后删除
                            store.drag = data;
                            store.drag_remove = true;
                        } else { // 拖动后不删除
                            store.drag = { node: utils.tree.clone(node), i: 0, path: 'readonly' };
                            store.drag_remove = false;
                        }
                        e.target.style.backgroundColor = '#bed7f8';
                    };
                    on.dragend = function(e) {
                        if (e.target !== e.currentTarget) return;
                        store.drag = null;
                        store.drag_remove = false;
                        e.target.style.backgroundColor = '';
                    };
                }
            }
            if (vue.readonly) {} else { // 编辑模式
                if (edr_abs) { // 随意拖动
                    on.mousedown = function(e) {
                        if (e.target !== e.currentTarget) return;
                        store.move_node = node;
                        store.move = e.target;
                        var sty = window.getComputedStyle(e.target);
                        store.move_begin = [e.pageX, e.pageY, parseFloat(sty.left), parseFloat(sty.top)];
                        store.move.style.backgroundColor = '#bed7f8';
                        store.move.style.cursor = 'move';
                        vue.moveTip(e, 'leave');
                        e.preventDefault();
                    };
                }
                on.dragover = function(e) {
                    if (e.target !== e.currentTarget) return;
                    var src = store.drag.path;
                    if (!src || path.startsWith(src)) return;
                    vue.moveTip(e);
                    e.preventDefault();
                };
                on.dragleave = function(e) {
                    if (e.target !== e.currentTarget) return;
                    var src = store.drag;
                    if (!src || path.startsWith(src.path)) return;
                    vue.moveTip(e, 'leave');
                };
                on.drop = function(e) {
                    if (e.target !== e.currentTarget) return;
                    console.log('drop');
                    var src = store.drag;
                    if (!src || path.startsWith(src.path)) return;
                    let p = utils.mousePosition(e);
                    utils.tree[p](store.drag, data, store.drag_remove);
                    console.log(JSON.stringify(vue.tree, null, 2));
                    e.preventDefault();
                };
                on.click = function(e) {
                    if (e.target !== e.currentTarget) return;
                    vue.$emit('select', data);
                    vue.select_data = data;
                    vue.select = node.key;
                };
            }
            if (node.attrs) Object.assign(item.attrs, node.attrs);
            if (node.on) Object.assign(on, node.on);
            if (/^[A-Z]/.test(node.name)) {
                item.nativeOn = on;
            } else {
                item.on = on;
            }
            Object.assign(item, node);
            // 选中样式
            item.class.edr_select = vue.select == node.key;
            if (sigle) return h(node.name, item, dfs({ node: node.children, parent: node, path, i }));
            return [h(node.name, item, dfs({ node: node.children, parent: node, path, i }))];
        }
        return h('div', {
            class: {
                'render': true
            },
            on: {
                mousemove(e) {
                    if (e.buttons) {
                        if (utils.store.move) {
                            var div = utils.store.move;
                            var b = utils.store.move_begin;
                            var node = utils.store.move_node;
                            node.style = node.style || {};
                            node.style.top = div.style.left = b[2] + e.pageX - b[0] + 'px';
                            node.style.top = div.style.top = b[3] + e.pageY - b[1] + 'px';
                        }
                    } else if (vue.effect) {
                        if (e.target !== e.currentTarget) {
                            vue.prev = e.target;
                            vue.moveTip(e, 'over');
                        }
                    }
                },
                mouseup(e) {
                    if (utils.store.move) {
                        utils.store.move.style.backgroundColor = '';
                        utils.store.move.style.cursor = '';
                        utils.store.move = null;
                    }
                    utils.store.move_begin = null;
                    utils.store.move_node = null;
                }
            }
        }, dfs(this.renderTree));
    },
    computed: {
        renderTree() {
            return { node: this.tree, parent: { children: this.tree }, path: '/' };
        }
    },
    methods: {
        moveTip(e, pos) {
            utils.move(this.tip, e, pos, this.$el);
        },
    },
    mounted() {
        var div = this.tip = document.createElement('div');
        div.className = 'tip leave';
        if (!this.readonly) {
            this.$el.appendChild(div);
        }
    }
};